package com.yuan.base.framework.http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.yuan.base.framework.BaseTokenManager;
import com.yuan.base.utils.LogUtil;
import com.yuan.base.utils.NetUtil;

import org.xutils.common.Callback;
import org.xutils.ex.HttpException;
import org.xutils.http.HttpMethod;
import org.xutils.http.RequestParams;
import org.xutils.x;

import java.io.File;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.HashMap;


/**
 */
public class BaseHttpRequest {
	private static String TAG = "BaseHttpRequest";

	public static Callback.Cancelable post(String url, HashMap<String, Object> params, BaseHttpCallBack callBack) {
		RequestParams p = BaseHttpRequest.getRequestParams(HttpMethod.POST, url, params, null);
		return BaseHttpRequest.doHttp(HttpMethod.POST, p, callBack);
	}

	public static Callback.Cancelable post(String url, File file, BaseHttpCallBack callBack) {
		RequestParams p = BaseHttpRequest.getRequestParams(HttpMethod.POST, url, null, file);
		return BaseHttpRequest.doHttp(HttpMethod.POST, p, callBack);
	}

	public static Callback.Cancelable get(String url, BaseHttpCallBack callBack) {
		RequestParams p = BaseHttpRequest.getRequestParams(HttpMethod.GET, url, null, null);
		return BaseHttpRequest.doHttp(HttpMethod.GET, p, callBack);
	}

	public static Callback.Cancelable get(String url, HashMap<String, Object> params, BaseHttpCallBack callBack) {
		RequestParams p = BaseHttpRequest.getRequestParams(HttpMethod.GET, url, params, null);
		return BaseHttpRequest.doHttp(HttpMethod.GET, p, callBack);
	}

	/**
	 * 获取基本参数配置，包括http的配置
	 */
	public static RequestParams getRequestParams(HttpMethod httpMethod, String url, HashMap<String, Object> params, File file) {
		RequestParams p = BaseHttpRequest.getRequestParams(url);
		if (params != null) {
			if (httpMethod == HttpMethod.GET) {
				for (HashMap.Entry<String, Object> entry : params.entrySet()) {
					p.addQueryStringParameter(entry.getKey(), String.valueOf(entry.getValue()));
				}
				String paramsStr = JSON.toJSONString(params);
				LogUtil.i(TAG + "-get-params", paramsStr);
			} else {
				String paramsStr = JSON.toJSONString(params);
				p.setBodyContent(paramsStr);
				LogUtil.i(TAG + "-post-params", paramsStr);
			}
		}
		if (file != null && file.exists()) {
			p.setMultipart(true);
			p.addBodyParameter("file", file, null, file.getName());
			LogUtil.i(TAG + "-post-upload", file.getPath());
		}
		return p;
	}

	/**
	 * 获取基本参数配置，包括http的配置
	 */
	public static RequestParams getRequestParams(String url) {
		LogUtil.i(TAG, url);
		RequestParams params = new RequestParams(url);
		params.setMaxRetryCount(0);
		params.setReadTimeout(1000 * 30);
		params.setConnectTimeout(1000 * 30);
		params.setCancelFast(true);
		params.setCacheMaxAge(0);
		params.setCacheSize(0);
		params.setUseCookie(false);
		params.setAsJsonContent(true);
		params.addHeader("Content-Type", "application/json");
		params.addHeader("Authorization", BaseTokenManager.getToken());
		return params;
	}

	public static Callback.Cancelable doHttp(HttpMethod httpMethod, RequestParams params, final BaseHttpCallBack callBack) {
		if (!NetUtil.isNetworkAvailable(x.app())) {
			callBack.onFailure(BaseErrorCode.CLIENT_NETWORK_ERROR, BaseErrorCode.errorMsg.get(BaseErrorCode.CLIENT_NETWORK_ERROR));
			callBack.onPost();
			return null;
		}
		Callback.Cancelable cancelable = x.http().request(httpMethod, params, new Callback.ProgressCallback<String>() {

			@Override
			public void onSuccess(String response) {
				LogUtil.i(TAG + "-response", response);
				try {
					if (!callBack.onComplete(response)) {
						return;
					}
					callBack.handleEntry(response);
//					JSONObject jsonObject;
//					try {
//						jsonObject = JSON.parseObject(response);
//					} catch (Exception e) {
//						throw new JSONException(e.getMessage());
//					}

//					if (jsonObject.getBooleanValue("success")) {
//						//成功
//						callBack.handleEntry(jsonObject);
//					} else {
//						//业务错误
//						callBack.onFailure(BaseErrorCode.STATUS_BUSINESS_ERROR, jsonObject.getString("message"));
//					}
				} catch (JSONException e) {
					LogUtil.e(TAG, "数据解析错误:" + BaseErrorCode.JSON_PARSE_ERROR + ",返回值:" + response);
					callBack.onFailure(BaseErrorCode.JSON_PARSE_ERROR, BaseErrorCode.errorMsg.get(BaseErrorCode.JSON_PARSE_ERROR, "内部错误,请将错误反馈给我们！"));
				}
			}

			@Override
			public void onError(Throwable ex, boolean isOnCallback) {
				if (ex instanceof HttpException) { // 网络错误
					HttpException httpEx = (HttpException) ex;
					int responseCode = httpEx.getCode();
					String responseMsg = httpEx.getMessage();
					String errorResult = httpEx.getResult();
					LogUtil.e(TAG, "errorCode : " + responseCode + ",msg : " + responseMsg + ", result: " + errorResult);
					if (BaseErrorCode.errorMsg.get(responseCode) != null) {
						callBack.onFailure(responseCode, BaseErrorCode.errorMsg.get(responseCode, ""));
					} else {
						callBack.onFailure(BaseErrorCode.UNKNOW_ERROR, BaseErrorCode.errorMsg.get(BaseErrorCode.UNKNOW_ERROR, ""));
					}
				} else if (ex instanceof SocketTimeoutException) { // 超时错误
					LogUtil.e(TAG, "errorCode : " + BaseErrorCode.TIMEOUT_ERROR + ",msg : " + BaseErrorCode.errorMsg.get(BaseErrorCode.TIMEOUT_ERROR, ""));
					callBack.onFailure(BaseErrorCode.TIMEOUT_ERROR, BaseErrorCode.errorMsg.get(BaseErrorCode.TIMEOUT_ERROR, ""));
				} else if (ex instanceof IOException) { // 连接失败
					LogUtil.e(TAG, "errorCode : " + BaseErrorCode.IO_ERROR + ",msg : " + BaseErrorCode.errorMsg.get(BaseErrorCode.IO_ERROR, ""));
					callBack.onFailure(BaseErrorCode.IO_ERROR, BaseErrorCode.errorMsg.get(BaseErrorCode.IO_ERROR, ""));
				} else {
					// 其他错误
					LogUtil.e(TAG, "errorCode : 0" + ",msg : " + ex.getMessage());
					callBack.onFailure(BaseErrorCode.UNKNOW_ERROR, BaseErrorCode.errorMsg.get(BaseErrorCode.UNKNOW_ERROR, ""));
				}
			}

			@Override
			public void onCancelled(CancelledException cex) {
			}

			@Override
			public void onFinished() {
				callBack.onPost();
			}

			@Override
			public void onWaiting() {
			}

			@Override
			public void onStarted() {
				callBack.onPreStart();
			}

			@Override
			public void onLoading(long total, long current, boolean isDownloading) {
				if (!isDownloading)
					callBack.onLoading(current, total);
			}
		});
		callBack.setCancelable(cancelable);
		return cancelable;
	}

}
